module.exports = grammar({
  name: 'dpml',

  extras: $ => [
    /\s/,
    $.comment
  ],

  rules: {
    // 文档根节点
    document: $ => repeat($._content),

    // 内容可以是元素或文本
    _content: $ => choice(
      $.element,
      $.text,
      $.resource_reference,
      $.term_reference
    ),

    // XML风格的元素
    element: $ => choice(
      $.self_closing_element,
      $.paired_element
    ),

    // 自闭合元素 <tag />
    self_closing_element: $ => seq(
      '<',
      $.tag_name,
      repeat($.attribute),
      '/',
      '>'
    ),

    // 配对元素 <tag>content</tag>
    paired_element: $ => seq(
      $.start_tag,
      repeat($._content),
      $.end_tag
    ),

    // 开始标签
    start_tag: $ => seq(
      '<',
      $.tag_name,
      repeat($.attribute),
      '>'
    ),

    // 结束标签
    end_tag: $ => seq(
      '</',
      $.tag_name,
      '>'
    ),

    // 标签名（支持命名空间）
    tag_name: $ => seq(
      $.identifier,
      optional(seq(':', $.identifier))
    ),

    // 属性
    attribute: $ => seq(
      $.identifier,
      '=',
      choice(
        $.quoted_string,
        $.single_quoted_string
      )
    ),

    // 标识符
    identifier: $ => /[a-zA-Z][a-zA-Z0-9_-]*/,

    // 双引号字符串
    quoted_string: $ => seq(
      '"',
      repeat(choice(
        /[^"\\]/,
        /\\./
      )),
      '"'
    ),

    // 单引号字符串
    single_quoted_string: $ => seq(
      "'",
      repeat(choice(
        /[^'\\]/,
        /\\./
      )),
      "'"
    ),

    // 资源引用 @protocol://path
    resource_reference: $ => seq(
      choice('@', '@!', '@?'),
      $.protocol_spec
    ),

    // 协议规范
    protocol_spec: $ => choice(
      // 简单协议 protocol://path
      seq(
        $.identifier,
        '://',
        $.resource_path,
        optional($.query_params)
      ),
      // 嵌套协议 outer:inner://path
      seq(
        $.identifier,
        ':',
        optional('@'),
        $.protocol_spec
      )
    ),

    // 资源路径
    resource_path: $ => /[^?\s<>]+/,

    // 查询参数
    query_params: $ => seq(
      '?',
      $.param_list
    ),

    // 参数列表
    param_list: $ => seq(
      $.param,
      repeat(seq('&', $.param))
    ),

    // 单个参数
    param: $ => seq(
      $.identifier,
      '=',
      /[^&\s<>]*/
    ),

    // 术语引用 #术语
    term_reference: $ => seq(
      '#',
      /[^\s<>]+/
    ),

    // 文本内容（Markdown）
    text: $ => /[^<@#]+/,

    // 注释
    comment: $ => seq(
      '<!--',
      /[^>]*(-[^>]+)*?/,
      '-->'
    )
  }
});
